package org.biz.core;

import org.apache.catalina.*;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.core.StandardContext;
import org.apache.catalina.core.StandardEngine;
import org.apache.catalina.core.StandardHost;
import org.apache.catalina.startup.Tomcat;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;


/**
 * @Author baoRoot
 * @CreateTime 2025/8/17
 * @Description
 */
public class SpringFactory {

  public static void run(Class<?> clazz, String[] args) {

    // 创建注解容器
    AnnotationConfigWebApplicationContext webApplicationContext = new AnnotationConfigWebApplicationContext();
    // 注册配置类， 所以SpringBootApplicationFactory注解中需要添加@Configuration注解的原因之一
    webApplicationContext.register(clazz);
    // 启动容器
    webApplicationContext.refresh();
    // 创建web服务器
    createTomcat(webApplicationContext);
  }

  private static void createTomcat(AnnotationConfigWebApplicationContext applicationContext) {
    Tomcat tomcat = new Tomcat();
    Server server = tomcat.getServer();
    Service service = server.findService("Tomcat");

    Connector connector = new Connector();
    connector.setPort(8082);
    connector.setURIEncoding("UTF-8");
    connector.setDiscardFacades(true);
    connector.setUseBodyEncodingForURI(true);

    Engine engine = new StandardEngine();
    engine.setDefaultHost("localhost");

    Host host = new StandardHost();
    host.setName("localhost");

    String contextPath = "";
    Context context = new StandardContext();
    context.setPath(contextPath);
    context.addLifecycleListener(new Tomcat.FixContextListener());

    host.addChild(context);
    engine.addChild(host);

    service.setContainer(engine);
    service.addConnector(connector);

    tomcat.addServlet(contextPath, "dispatcher", new DispatcherServlet(applicationContext));
    context.addServletMappingDecoded("/*", "dispatcher");

    try {
      tomcat.start();
    } catch (LifecycleException e) {
      e.fillInStackTrace();
    }
  }

}
